﻿using AtomUI.Controls;
using Avalonia.Threading;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using SD.App.Desktop.Service;
using SD.App.Desktop.Utils;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace SD.App.Desktop.ViewModels
{
    public class LoginViewModel : ReactiveObject, ITransientLifetime
    {
        // 注入封装后的 IMessageService
        private readonly IMessageService _messageService;
        // Autofac 会自动注入 ILogger
        private readonly ILogger _logger;
        private readonly IUserService _userService;


        [Reactive]
        public string UserName { get; set; } = "";

        [Reactive]
        public string Password { get; set; } = "";

        [Reactive]
        public bool IsShowLoginErrorText { get; set; } = false;

        [Reactive]
        public bool IsLoading { get; set; } = false;

        [Reactive]
        public bool Remember { get; set; } = false;

        // 错误信息
        [Reactive]
        public string UsernameError { get; set; } = string.Empty;
        [Reactive]
        public string PasswordError { get; set; } = string.Empty;

        // 2. 响应式命令（无参数，返回 Unit 表示无返回值）
        public ReactiveCommand<Unit, Unit> LoginCommand { get; }

        public RoutingState Router { get; } = new RoutingState();

        private readonly CompositeDisposable _disposables = new();
         
        public LoginViewModel(ILogger logger,
            IMessageService messageService,
            IUserService userService)
        {
            _logger = logger;
            _messageService = messageService;
            _userService = userService;

            // 1. 用户名校验流：必填 + 长度（3-20位）
            var usernameValidate = this.WhenAnyValue(vm => vm.UserName)
                .Skip(1) // 跳过初始值（空字符串）的校验触发
                .Select(username =>
                {
                    // 先校验必填，再校验长度（短路逻辑：必填失败则不进入长度校验）
                    var requiredError = ValidateRules.Required(username, "用户名");
                    if (!string.IsNullOrEmpty(requiredError))
                        return requiredError;

                    // 必填通过后，进入长度校验
                    return ValidateRules.Length(username, 3, 20, "用户名");
                });

            var passwordValidate = this.WhenAnyValue(vm => vm.Password)
                .Skip(1)
                .Select(password => {
                    // 校验必填
                    var requireError = ValidateRules.Required(password, "密码");
                    return requireError;
                });

            // 5. 绑定校验结果到错误字段（关键：确保校验流输出被接收）
            usernameValidate
                .BindTo(this, vm => vm.UsernameError)
                .DisposeWith(_disposables);

            passwordValidate
                .BindTo(this, vm => vm.PasswordError)
                .DisposeWith(_disposables);

            // 6. 提交按钮状态：所有错误字段为空
            var canSubmit = this.WhenAnyValue(
                vm => vm.UserName,
                vm => vm.Password,
                vm => vm.UsernameError,
                vm => vm.PasswordError,
                (name, password, u, p) => !string.IsNullOrEmpty(name)
                    && !string.IsNullOrEmpty(Password)
                    && string.IsNullOrEmpty(u)
                    && string.IsNullOrEmpty(p));

            // 7. 命令实现
            LoginCommand = ReactiveCommand.Create(() =>
            {
                // 业务逻辑：动态生成文本（可替换为数据计算、接口请求等）

                Login();


            }, canSubmit);

        }

        private void Login()
        {
            Dispatcher.UIThread.InvokeAsync(async () =>
            {
                IsLoading = true;
                IsShowLoginErrorText = false;

                // 模拟操作处理时间
                // await Task.Delay(TimeSpan.FromSeconds(3));

                var userName = UserName;
                var password = Password;

                var user = await _userService.LoginAsync(userName, password);

                if (user != null)
                {
                    // 登录成功
                    IsShowLoginErrorText = false;
                    _messageService.ShowSuccess("登录成功");

                }
                else
                {
                    _messageService.ShowError("用户名或密码错误");
                    _logger.Error("用户名或密码错误");

                    // 登录失败
                    //IsShowLoginErrorText = true;
                }

                IsLoading = false;
            });

        }
    }
}
